/*********************
* Author:Dzlua
* QQ:505544956
* time:2016/11/03
*/
#ifndef __EDUI_EDIT_H__
#define __EDUI_EDIT_H__

#include "Label.h"

EDUI_NAMESPACE_BEGIN

class ITexture;

class EDUI_API Edit : public Label
{
    friend Uint32 _TimerCallback(TimerID id, Uint32 interval, IWindow* wnd, void *data1, void* data2);
public:
    struct {
        Event1<Edit*> textChange;
        Event1<Edit*> onEnter;
    } evt;
protected:
    Edit();
    virtual ~Edit();
public:
	static Edit* GetInterface();
	virtual void Release();
    static Edit* ToEdit(Control* ctrl);
public:
    //bWindow:if not font,use window's font
    IFont* GetTipFont(bool bWindow = true) const;
    bool SetTipFont(IFont* font);

    virtual void SetText(const char* text);
    //paste:keyboard input or paste,readonly can not use this function.
    bool ReplaceText(const char* text, int begin, int end, bool paste = true);
    //readonly can not use this function.
    bool DeleteText(int begin, int end);
    void ClearText();
    String GetText(int begin, int end) const;//[begin,end)
    virtual const char* GetText() const;

    void SelAllText();
    void SelText(int begin, int end);
    //readonly can not use this function.
    void ReplaceSel(const char* text, bool paste = true);
    //readonly can not use this function.
    void DeleteSel();
    bool GetSel(int* begin, int* end) const;
    String GetSelText() const;
    bool GetSelPos(int* begin, int* end) const;

    //readonly can not use this function.
    void DeletePrev();
    //readonly can not use this function.
    void DeleteNext();

    //copy,cut to clipboard.
    void Copy();//copy sel text.
    void Cut();//cut sel text.readonly can not use this function.
    void Paste();//paste text instead of sel text.readonly can not use this function.
    void Delete();//delete sel text.readonly can not use this function.
    void BackSpace();//readonly can not use this function.

    //about cursor
    void SetCursorNextPos();
    void SetCursorPrevPos();
    void SetCursorPos(int pos);
    int GetCursorPos() const;

    void EnableCursor(bool bEnable);
    void EnableSel(bool bEnable);
    void ReadOnly(bool bOnlyRead);

    // <=0 if not limit.
    void SetMaxChar(int maxchar);

    void SetTipText(const char* text);
    const char* GetTipText() const;

    void SetReadOnly(bool readonly);
    bool IsReadOnly() const;

    void SetUsePassWord(bool use);
    bool IsUsedPassWord() const;
    const char* GetPassWordText() const;
    void SetPassWordMask(const char* mask);
    const char* GetPassWordMask() const;

    //set input limit by regex
    void SetInputRegex(const char* regex);
    //set verify limit by regex
    void SetVerifyRegex(const char* regex);
    // verify edit text if ok by verify regex
    // if not set verify regex,return true.
    bool Verify();
    // verify edit text if ok by given regex
    // if regex is 0,return false
    bool Verify(const char* regex);
protected:
    virtual bool HandleMsg(Msg* msg);
    virtual void RenderStatusImages(IRender* render, const Rect* rc);
    virtual void RenderText(IRender* render, const Rect* rc);
    virtual void RenderSelBk(IRender* render);
    virtual void RenderCursor(IRender* render);

    virtual void SetAttribute(const char* name, const char* value);
    virtual Color* GetDestColor(const char* dstname);
    virtual ImageData* GetDestImageData(const char* dstname);

    virtual void DoEvent(EventType type, void* data1 = 0, void* data2 = 0);

    bool HandleMsgButton(Msg* msg);
    bool HandleMsgMouse(Msg* msg);
    bool HandleMsgKeyboard(Msg* msg);
protected:
    virtual void UpdateTexture();
    virtual void UpdateCursor();

    bool TextIndex2Pos(const char* text, int inBegin, int inEnd,int* outBegin, int* outEnd) const;

    // return -1 if failed.
    int Mouse2CursorPos(int x, int y);
    bool GetSelRect(Rect* rc);
    bool GetCursorRect(Rect* rc);

    //check limit maxchar.return->0:ok,>0: pos if maxchar,<0 error.
    int CheckMaxChar(const char* text, int ignoreSize = 0) const;

    // return n *
    String GetSomeMaskChar(int num);

    // return true if pcre==0; return false if text==0;
    bool IsRegexMatch(void* pcre, const char* text);
protected:
    virtual void OnFocus();
    virtual void OnKillFocus();
protected:
    int m_iSelBegin, m_iSelEnd;
    int m_iCursorPos, m_iCursorMaxPos;
    bool m_bSeled, m_bSelEnabled;
    bool m_bCursorShow, m_bCursorEnabled, m_bCursorEditing;
    bool m_bReadOnly;

    int m_iShiftSelDirection;//press key shift + arrow,left/right add/erase sel
    int m_textTextureOffset;

    //ITexture* m_textTexture;

    ButtonState m_state;
    ImageData m_normalImage;
    ImageData m_hotImage;
    ImageData m_pressedImage;
    ImageData m_disabledImage;

    TimerID m_timer;

    int m_maxChar;
    
    String m_tipText;
    Color m_tipTextColor;
    IFont* m_tipFont;

    bool m_bPassword;
    String m_passWordText;
    String m_passWordMask;

    Color m_selBkColor;

    //pcrepp::Pcre* m_regexInput;
    //pcrepp::Pcre* m_regexVerify;
    void* m_regexInput;
    void* m_regexVerify;
};

EDUI_NAMESPACE_END

#endif